<template>
  <view class="container">
    <view class="header">
      <view class="back-btn" @click="goBack">返回</view>
      <view class="title">球场预定</view>
    </view>
    <scroll-view class="date-scroll" scroll-x>
      <view class="date-list">
        <view
          v-for="(item, idx) in dateOptions"
          :key="item.date"
          :class="['date-item', idx === selectedDateIndex ? 'active' : '']"
          @click="onDateSelect(idx)"
        >
          <view class="date-week">{{ item.week }}</view>
          <view class="date-day">{{ item.display }}</view>
          <view class="date-info">剩{{ item.availableCount }}场</view>
          <view class="date-price">￥{{ item.price }}起</view>
        </view>
      </view>
    </scroll-view>
    <view class="table-wrap">
      <view class="time-col">
        <view class="time-header-placeholder"></view>
        <view v-for="slot in filteredTimeSlots" :key="slot" class="time-cell-fixed">{{ slot }}</view>
      </view>
      <scroll-view class="table-scroll" scroll-x>
        <view class="table">
          <view class="table-row table-header">
            <view v-for="court in courts" :key="court.id" class="table-cell court-header">{{ court.name }}</view>
          </view>
          <view v-for="slot in filteredTimeSlots" :key="slot" class="table-row">
            <view v-for="court in courts" :key="court.id" class="table-cell">
              <view
                :class="cellClass(court.id, slot)"
                @click="toggleSelect(court.id, slot)"
              >
                {{ cellText(court.id, slot) }}
              </view>
            </view>
          </view>
        </view>
      </scroll-view>
    </view>
    <button class="btn-primary submit-btn" :loading="loading" :disabled="loading || selectedList.length===0" @click="submitBooking">
      {{ loading ? '提交中...' : '提交预定' }}
    </button>
  </view>
</template>

<script>
import { createBooking } from '../../api/booking.js'
import request from '../../utils/request.js'
import { getCourtList } from '../../api/court.js'

const TIME_SLOTS = [
  '08:00-09:00', '09:00-10:00', '10:00-11:00', '11:00-12:00',
  '12:00-13:00', '13:00-14:00', '14:00-15:00', '15:00-16:00',
  '16:00-17:00', '17:00-18:00', '18:00-19:00', '19:00-20:00',
  '20:00-21:00', '21:00-22:00'
]

function getWeekStr(date) {
  const arr = ['日','一','二','三','四','五','六']
  return '周' + arr[date.getDay()]
}

function getDisplayStr(date) {
  return `${date.getMonth()+1}-${date.getDate()}`
}

const MAX_SELECT = 5

export default {
  data() {
    return {
      courts: [],
      bookings: {}, // { [courtId]: { [slot]: 状态 } }
      selected: {}, // { [courtId]: Set(slot) }
      loading: false,
      timeSlots: TIME_SLOTS,
      dateOptions: [], // [{date, week, display, availableCount, price}]
      selectedDateIndex: 0,
      now: new Date()
    }
  },
  computed: {
    date() {
      return this.dateOptions[this.selectedDateIndex]?.date || ''
    },
    filteredTimeSlots() {
      // 只显示未过期时间段
      if (!this.isToday) return this.timeSlots
      const nowHour = this.now.getHours()
      const nowMin = this.now.getMinutes()
      return this.timeSlots.filter(slot => {
        const [start] = slot.split('-')
        const [h, m] = start.split(':').map(Number)
        return h > nowHour || (h === nowHour && m > nowMin)
      })
    },
    selectedList() {
      // 返回所有选中的 {courtId, slot}
      const arr = []
      for (const courtId in this.selected) {
        for (const slot of this.selected[courtId]) {
          arr.push({ courtId, slot })
        }
      }
      return arr
    },
    isToday() {
      const today = this.formatDate(this.now)
      return this.date === today
    }
  },
  onLoad() {
    this.initDateOptions()
    this.initData()
    this.timer = setInterval(() => { this.now = new Date() }, 60000)
  },
  onUnload() {
    clearInterval(this.timer)
  },
  methods: {
    formatDate(date) {
      const y = date.getFullYear()
      const m = (date.getMonth() + 1).toString().padStart(2, '0')
      const d = date.getDate().toString().padStart(2, '0')
      return `${y}-${m}-${d}`
    },
    goBack() {
      uni.navigateBack()
    },
    async initDateOptions() {
      // 生成未来7天日期
      const arr = []
      const courtRes = await getCourtList()
      const courts = courtRes.data || courtRes
      for (let i = 0; i < 7; i++) {
        const d = new Date()
        d.setDate(d.getDate() + i)
        const dateStr = this.formatDate(d)
        // 获取可定场次
        let availableCount = 0
        let price = courts.length ? Math.min(...courts.map(c => c.price || 0)) : 0
        // 查询接口
        let bookingRes = await request({ url: `/api/booking/availability?date=${dateStr}`, method: 'GET' })
        let bookings = bookingRes.data || {}
        for (const court of courts) {
          for (const slot of TIME_SLOTS) {
            if (bookings[court.id]?.[slot] === 'free') availableCount++
          }
        }
        arr.push({
          date: dateStr,
          week: getWeekStr(d),
          display: getDisplayStr(d),
          availableCount,
          price
        })
      }
      this.dateOptions = arr
    },
    async initData() {
      // 获取球场列表
      const courtRes = await getCourtList()
      this.courts = courtRes.data || courtRes
      // 获取预定状态
      const bookingRes = await request({ url: `/api/booking/availability?date=${this.date}`, method: 'GET' })
      this.bookings = bookingRes.data || {}
      this.selected = {}
    },
    onDateSelect(idx) {
      this.selectedDateIndex = idx
      this.initData()
    },
    cellClass(courtId, slot) {
      const status = this.bookings?.[courtId]?.[slot]
      if (status === 'booked') return 'cell booked'
      if (this.selected[courtId]?.has(slot)) return 'cell selected'
      return 'cell free'
    },
    cellText(courtId, slot) {
      const status = this.bookings?.[courtId]?.[slot]
      if (status === 'booked') return '已预定'
      if (this.selected[courtId]?.has(slot)) return '已选'
      return '空闲'
    },
    toggleSelect(courtId, slot) {
      if (this.bookings?.[courtId]?.[slot] === 'booked') return
      const total = this.selectedList.length
      const alreadySelected = this.selected[courtId]?.has(slot)
      if (!alreadySelected && total >= MAX_SELECT) {
        uni.showModal({ title: '提示', content: `最多只能预定${MAX_SELECT}个场次`, showCancel: false })
        return
      }
      if (!this.selected[courtId]) this.selected[courtId] = new Set()
      if (alreadySelected) {
        this.selected[courtId].delete(slot)
        if (this.selected[courtId].size === 0) delete this.selected[courtId]
      } else {
        this.selected[courtId].add(slot)
      }
      this.$forceUpdate()
    },
    async submitBooking() {
      if (this.loading || this.selectedList.length === 0) return
      this.loading = true
      try {
        for (const { courtId, slot } of this.selectedList) {
          await createBooking({ courtId, date: this.date, timeSlot: slot })
        }
        uni.showToast({ title: '预定成功', icon: 'success' })
        setTimeout(() => {
          uni.redirectTo({ url: '/pages/booking/my' })
        }, 800)
      } catch (err) {
        uni.showModal({ title: '预定失败', content: err?.msg || '请稍后重试', showCancel: false })
      } finally {
        this.loading = false
      }
    }
  }
}
</script>

<style scoped>
.container {
  padding: 24px 8px 80px 8px;
  min-height: 100vh;
  background: #f7f8fa;
}
.header {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
}
.back-btn {
  color: #007aff;
  font-size: 16px;
  margin-right: 16px;
  padding: 4px 8px;
  border-radius: 4px;
  background: #e6f0ff;
}
.title {
  font-size: 20px;
  font-weight: bold;
}
.date-scroll {
  width: 100%;
  white-space: nowrap;
  margin-bottom: 8px;
}
.date-list {
  display: flex;
}
.date-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-width: 80px;
  padding: 8px 6px;
  margin-right: 8px;
  background: #fff;
  border-radius: 10px;
  box-shadow: 0 2px 8px #eee;
  cursor: pointer;
  border: 2px solid transparent;
  transition: border 0.2s;
}
.date-item.active {
  border: 2px solid #36d1c5;
}
.date-week {
  font-size: 13px;
  color: #888;
}
.date-day {
  font-size: 17px;
  font-weight: bold;
  margin: 2px 0;
}
.date-info {
  font-size: 12px;
  color: #1abc9c;
}
.date-price {
  font-size: 12px;
  color: #e67e22;
}
.table-wrap {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  width: 100%;
  margin-bottom: 8px;
}
.time-col {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  min-width: 90px;
  margin-right: 2px;
}
.time-header-placeholder {
  min-width: 90px;
  height: 40px;
  background: transparent;
}
.time-header {
  display: none;
}
.time-cell-fixed {
  min-width: 90px;
  text-align: right;
  padding: 8px 0;
  background: #f7f8fa;
  border-bottom: 1px solid #f0f0f0;
}
.table-scroll {
  overflow-x: auto;
  flex: 1;
}
.table {
  min-width: 400px;
  background: #fff;
  border-radius: 0 12px 12px 12px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.04);
  padding: 12px 0;
}
.table-row {
  display: flex;
  align-items: center;
}
.table-header {
  font-weight: bold;
  background: #f0f4fa;
}
.table-cell {
  flex: 0 0 70px;
  min-width: 70px;
  max-width: 90px;
  text-align: center;
  padding: 8px 0;
  border-bottom: 1px solid #f0f0f0;
}
.court-header {
  min-width: 70px;
  max-width: 90px;
}
.cell {
  border-radius: 8px;
  padding: 6px 0;
  margin: 0 2px;
  cursor: pointer;
  transition: background 0.2s;
  font-size: 14px;
}
.cell.free {
  background: #e6f9f0;
  color: #1abc9c;
}
.cell.selected {
  background: linear-gradient(90deg, #36d1c5 0%, #5b86e5 100%);
  color: #fff;
}
.cell.booked {
  background: #f5f5f5;
  color: #bbb;
  cursor: not-allowed;
}
.submit-btn {
  width: 100%;
  height: 44px;
  background: linear-gradient(90deg, #36d1c5 0%, #5b86e5 100%);
  color: #fff;
  font-size: 16px;
  border: none;
  border-radius: 22px;
  box-shadow: 0 2px 8px rgba(91,134,229,0.10);
  margin-top: 18px;
  position: fixed;
  left: 0;
  bottom: 0;
  z-index: 10;
}
.submit-btn[disabled] {
  opacity: 0.7;
}
</style> 